#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "debug.h"
#include "os_api.h"
#include "ps_api.h"
#include "dev_api.h"
#include "audio_api.h"
#include "atclient.h"


#define _STACK_SIZE	(1024*3)
static void* _task_stack = NULL;
static OSTaskRef _task_ref = NULL;

typedef struct{    
    int len;
    UINT8 *data;
}commonIndParam;

#define COM_STACK_SIZE	(1024*3)
static void* com_task_stack = NULL;
static OSTaskRef com_task_ref = NULL;
static OSMsgQRef commonIndMsgQ = NULL;


void wait_network_ready(void)
{
    int count = 30;
    while(count-- && ps_GetNetworkReady() == FALSE){	
        OSATaskSleep(200);
    }

    if (count <= 0){
        LOG_PRINTF("dev_CtrlReset.\n");
        dev_CtrlReset(0);
    }
}

static void _task(void *ptr)
{	
	int ret;
	char resp_str[128]={'\0'};

	int ims_ready = 0;
	
	wait_network_ready();	

	// 语音通道使用内部codec
	AudioHAL_AifUseInternalCodec();
	// 语音通道使用pcm
	//AudioHAL_AifUseSSPA();
	
	// AT+CIREG?
	while (!ims_ready){
		ret = atclient_send("AT+CIREG?\r\n", 3, 1, resp_str, sizeof(resp_str));
		LOG_PRINTF("%s: resp_str = %s, ret = %u\n",__FUNCTION__,resp_str,ret);
		if(strstr(resp_str, "+CIREG: 1,1,") != NULL ){
			ims_ready = 1;
		}
		OSATaskSleep(200);
	}
	
	// AT+CNMI
	ret = atclient_send("ATD1312276xxxx;\r\n", 3, 1, resp_str, sizeof(resp_str));
	LOG_PRINTF("%s: resp_str = %s, ret = %u\n",__FUNCTION__,resp_str,ret);
	
	OSATaskSleep(200*10);

	// AT+CHUP
	ret = atclient_send("AT+CHUP\r\n", 3, 1, resp_str, sizeof(resp_str));
	LOG_PRINTF("%s: resp_str = %s, ret = %u\n",__FUNCTION__,resp_str,ret);	
}

void commonIndRecvCallback(UINT8 * recv_data, UINT32 recv_len)
{	
	commonIndParam commonInd_data = {0};
    OSA_STATUS osa_status;
    
    char *tempbuf = (char *)malloc(recv_len+1);
    memset(tempbuf, 0x0, recv_len+1);
    memcpy(tempbuf, (char *)recv_data, recv_len);

    commonInd_data.data = (UINT8 *)tempbuf;
    commonInd_data.len = recv_len;
	
    osa_status = OSAMsgQSend(commonIndMsgQ, sizeof(commonIndParam), (UINT8*)&commonInd_data, OSA_NO_SUSPEND);
    ASSERT(osa_status == OS_SUCCESS);
}


void atIndCallback(const char *indication)
{	
	OSA_STATUS osa_status;
	commonIndParam commonInd_data = {0};

    commonInd_data.data = strdup(indication);
    commonInd_data.len = strlen(indication);
	
    osa_status = OSAMsgQSend(commonIndMsgQ, sizeof(commonIndParam), (UINT8*)&commonInd_data, OSA_NO_SUSPEND);
    ASSERT(osa_status == OS_SUCCESS);
}

static void com_task(void *ptr)
{
	int ret;
    int rcv = 0;    
    OSA_STATUS status;
	commonIndParam commonInd_temp;	

	atclient_set_ind_cb(atIndCallback);
	
    while (1) {
        memset(&commonInd_temp, 0, sizeof(commonIndParam));        
        status = OSAMsgQRecv(commonIndMsgQ, (UINT8 *)&commonInd_temp, sizeof(commonIndParam), OSA_SUSPEND);
        
        if (status == OS_SUCCESS) {
            if (commonInd_temp.data) {
                LOG_PRINTF("%s[%d]: commonInd_temp len:%d, data:%s\n", __FUNCTION__, __LINE__, commonInd_temp.len, (char *)(commonInd_temp.data));
								
				//volte URC: RING、^ORIG、^CONN、^CEND、+CLCC、+COLP
				
				if (strstr((char *)commonInd_temp.data, "RING")
					||strstr((char *)commonInd_temp.data, "^ORIG")
					||strstr((char *)commonInd_temp.data, "^CONN")
					||strstr((char *)commonInd_temp.data, "^CEND")
					||strstr((char *)commonInd_temp.data, "+CLCC")
					||strstr((char *)commonInd_temp.data, "+COLP")){
						
					LOG_PRINTF("volte URC: len:%d, data:%s\n", commonInd_temp.len, (char *)(commonInd_temp.data));	
				}
				
				free(commonInd_temp.data);
            }
        }
    }
}


int main(void)
{
    int ret;
	
	_task_stack = malloc(_STACK_SIZE);
	ASSERT(_task_stack != NULL);
	
    ret = OSATaskCreate(&_task_ref, _task_stack, _STACK_SIZE, 100, "_task", _task, NULL);
    ASSERT(ret == OS_SUCCESS);
			
    ret = OSAMsgQCreate(&commonIndMsgQ, "commonIndMsgQ", sizeof(commonIndParam), 300, OS_FIFO);
    ASSERT(ret == OS_SUCCESS);	
	
	com_task_stack = malloc(COM_STACK_SIZE);
	ASSERT(com_task_stack != NULL);
	
    ret = OSATaskCreate(&com_task_ref, com_task_stack, COM_STACK_SIZE, 100, "com_task", com_task, NULL);
    ASSERT(ret == OS_SUCCESS);	

	return 0;
}
